#include "serializer/serializer.h"

#include <gtest/gtest.h>

#include <atomic>
#include <stdexcept>
#include <string>
#include <thread>
#include <vector>

using namespace serializer;

/**
 * 抛出异常的写入器，用于测试序列化错误处理
 */
class ThrowingWriter
{
private:
    std::vector<std::byte> buffer_;
    size_t throw_after_bytes_;
    size_t bytes_written_;

public:
    /**
     * 构造函数
     * @param throw_after_bytes 写入多少字节后抛出异常
     */
    explicit ThrowingWriter(size_t throw_after_bytes = 0)
        : throw_after_bytes_(throw_after_bytes), bytes_written_(0)
    {
    }

    /**
     * 写入字节数据
     * @param data 要写入的数据
     * @param size 数据大小
     * @throws std::runtime_error 当写入字节数超过阈值时
     */
    void write_bytes(const std::byte * data, size_t size)
    {
        if (bytes_written_ + size > throw_after_bytes_)
        {
            throw std::runtime_error("Writer error: exceeded byte limit");
        }
        buffer_.insert(buffer_.end(), data, data + size);
        bytes_written_ += size;
    }

    /**
     * 写入字符串视图
     * @param sv 要写入的字符串视图
     * @throws std::runtime_error 当写入字节数超过阈值时
     */
    void write_string_view(std::string_view sv)
    {
        write_bytes(reinterpret_cast<const std::byte *>(sv.data()), sv.size());
    }

    /**
     * 获取当前位置
     * @return 当前位置
     */
    size_t position() const noexcept { return bytes_written_; }

    /**
     * 获取已写入字节数
     * @return 已写入字节数
     */
    size_t bytes_written() const noexcept { return bytes_written_; }

    /**
     * 获取缓冲区数据
     * @return 缓冲区的常量引用
     */
    const std::vector<std::byte> & data() const { return buffer_; }
};

/**
 * 抛出异常的读取器，用于测试反序列化错误处理
 */
class ThrowingReader
{
private:
    const std::vector<std::byte> & buffer_;
    size_t position_;
    size_t throw_after_bytes_;
    size_t bytes_read_;

public:
    /**
     * 构造函数
     * @param buffer 要读取的数据缓冲区
     * @param throw_after_bytes 读取多少字节后抛出异常
     */
    explicit ThrowingReader(const std::vector<std::byte> & buffer, size_t throw_after_bytes = 0)
        : buffer_(buffer), position_(0), throw_after_bytes_(throw_after_bytes), bytes_read_(0)
    {
    }

    /**
     * 读取字节数据
     * @param data 存储读取数据的缓冲区
     * @param size 要读取的字节数
     * @throws std::runtime_error 当读取字节数超过阈值时
     */
    void read_bytes(std::byte * data, size_t size)
    {
        if (bytes_read_ + size > throw_after_bytes_)
        {
            throw std::runtime_error("Reader error: exceeded byte limit");
        }
        if (position_ + size > buffer_.size())
        {
            throw std::runtime_error("Reader error: insufficient data");
        }
        std::copy(buffer_.begin() + position_, buffer_.begin() + position_ + size, data);
        position_ += size;
        bytes_read_ += size;
    }

    /**
     * 读取字符串
     * @param size 要读取的字符串长度
     * @return 读取的字符串
     * @throws std::runtime_error 当读取字节数超过阈值时
     */
    std::string read_string(size_t size)
    {
        std::string result(size, '\0');
        read_bytes(reinterpret_cast<std::byte *>(result.data()), size);
        return result;
    }

    /**
     * 获取当前位置
     * @return 当前位置
     */
    size_t position() const noexcept { return position_; }

    /**
     * 设置位置
     * @param pos 新位置
     */
    void seek(size_t pos) noexcept { position_ = pos; }

    /**
     * 检查是否还有数据可读
     * @return 如果还有数据可读则返回true
     */
    bool has_data() const noexcept { return position_ < buffer_.size(); }
};

/**
 * 测试序列化过程中的异常处理
 */
TEST(ErrorHandlingTest, serialization_exception_handling)
{
    std::vector<int> test_data = {1, 2, 3, 4, 5};
    ThrowingWriter throwing_writer(5); // 写入5字节后抛出异常

    // 序列化应该抛出异常
    EXPECT_THROW(serialize(throwing_writer, test_data, default_options{}), std::runtime_error);
}

/**
 * 测试反序列化过程中的异常处理
 */
TEST(ErrorHandlingTest, deserialization_exception_handling)
{
    std::vector<int> original_data = {1, 2, 3, 4, 5};
    vector_writer writer;
    serialize(writer, original_data, default_options{});

    ThrowingReader throwing_reader(writer.data(), 5); // 读取5字节后抛出异常

    // 反序列化应该抛出异常
    EXPECT_THROW(deserialize<std::vector<int>>(throwing_reader, default_options{}),
                 std::runtime_error);
}

/**
 * 测试数据不足时的错误处理
 */
TEST(ErrorHandlingTest, insufficient_data_error)
{
    std::vector<std::byte> incomplete_data = {std::byte{0x01}, std::byte{0x02}};
    vector_reader reader(incomplete_data);

    // 尝试反序列化一个需要更多数据的对象
    EXPECT_THROW(deserialize<std::vector<int>>(reader, default_options{}), std::runtime_error);
}

/**
 * 测试数据损坏时的错误处理
 */
TEST(ErrorHandlingTest, corrupted_data_error)
{
    // 创建一些看起来像有效数据但实际损坏的数据
    std::vector<std::byte> corrupted_data;
    for (int i = 0; i < 100; ++i)
    {
        corrupted_data.push_back(std::byte{static_cast<unsigned char>(i % 256)});
    }

    vector_reader reader(corrupted_data);

    // 尝试反序列化可能会因为数据损坏而失败
    EXPECT_THROW(deserialize<std::string>(reader, default_options{}), std::runtime_error);
}

/**
 * 测试字节序处理中的错误
 */
TEST(ErrorHandlingTest, byte_order_handling)
{
    int test_data = 0x12345678;
    vector_writer writer;

    // 使用大端序序列化
    auto big_endian_options = default_options{}.with_byte_order(byte_order::big_endian);
    serialize(writer, test_data, big_endian_options);

    vector_reader reader(writer.data());

    // 使用相同的字节序反序列化应该成功
    auto deserialized = deserialize<int>(reader, big_endian_options);
    EXPECT_EQ(test_data, deserialized);

    // 测试不同字节序的序列化和反序列化
    vector_writer writer2;
    auto little_endian_options = default_options{}.with_byte_order(byte_order::little_endian);
    serialize(writer2, test_data, little_endian_options);

    vector_reader reader2(writer2.data());
    auto deserialized2 = deserialize<int>(reader2, little_endian_options);
    EXPECT_EQ(test_data, deserialized2);
}

/**
 * 测试内存分配失败的模拟
 */
TEST(ErrorHandlingTest, memory_allocation_failure_simulation)
{
    // 创建一个非常大的向量来模拟内存分配失败
    vector_writer writer;
    size_t huge_size = SIZE_MAX / 2;
    writer.write_bytes(reinterpret_cast<const std::byte *>(&huge_size), sizeof(huge_size));

    vector_reader reader(writer.data());

    // 尝试反序列化应该失败（由于内存分配失败或大小检查）
    EXPECT_THROW(deserialize<std::vector<int>>(reader, default_options{}), std::exception);
}

/**
 * 测试嵌套异常处理
 */
TEST(ErrorHandlingTest, nested_exception_handling)
{
    try
    {
        ThrowingWriter throwing_writer(0); // 立即抛出异常
        std::vector<std::string> test_data = {"test1", "test2", "test3"};

        try
        {
            serialize(throwing_writer, test_data, default_options{});
            FAIL() << "Expected exception was not thrown";
        }
        catch (const std::runtime_error & e)
        {
            // 重新抛出一个嵌套异常
            std::throw_with_nested(std::logic_error("Nested error occurred"));
        }
    }
    catch (const std::logic_error & e)
    {
        // 验证我们可以捕获嵌套异常
        EXPECT_STREQ(e.what(), "Nested error occurred");

        try
        {
            std::rethrow_if_nested(e);
        }
        catch (const std::runtime_error & nested)
        {
            EXPECT_TRUE(std::string(nested.what()).find("Writer error") != std::string::npos);
        }
    }
}

// 全局资源跟踪器，避免局部类的静态成员问题
class ResourceTracker
{
public:
    static std::atomic<int> active_count;
    int dummy_value = 42; // 添加一个可序列化的成员

    ResourceTracker() { active_count++; }
    ~ResourceTracker() { active_count--; }
    ResourceTracker(const ResourceTracker &) { active_count++; }
    ResourceTracker & operator=(const ResourceTracker &) = default;

    /**
     * 序列化函数
     * @param writer 写入器
     * @param options 序列化选项
     */
    template <typename Writer, typename Options>
    void serialize(Writer & writer, const Options & options) const
    {
        serialize(writer, dummy_value, options);
    }

    /**
     * 反序列化函数
     * @param reader 读取器
     * @param options 反序列化选项
     * @return 反序列化的对象
     */
    template <typename Reader, typename Options>
    static ResourceTracker deserialize(Reader & reader, const Options & options)
    {
        ResourceTracker result;
        result.dummy_value = deserialize<int>(reader, options);
        return result;
    }
};

// 定义静态成员
std::atomic<int> ResourceTracker::active_count{0};

/**
 * 测试资源清理和RAII
 */
TEST(ErrorHandlingTest, resource_cleanup_and_raii)
{
    ResourceTracker::active_count = 0;

    {
        std::vector<ResourceTracker> resources(10);
        EXPECT_EQ(ResourceTracker::active_count.load(), 10);

        // 使用简单的int向量进行序列化测试
        std::vector<int> simple_data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        ThrowingWriter throwing_writer(5);

        // 序列化失败应该不影响资源清理
        EXPECT_THROW(serialize(throwing_writer, simple_data, default_options{}),
                     std::runtime_error);

        EXPECT_EQ(ResourceTracker::active_count.load(), 10); // 资源仍然存在
    }

    // 离开作用域后，所有资源应该被清理
    EXPECT_EQ(ResourceTracker::active_count.load(), 0);
}

/**
 * 测试边界条件错误
 */
TEST(ErrorHandlingTest, boundary_condition_errors)
{
    // 测试空容器
    std::vector<int> empty_vector;
    vector_writer writer;
    EXPECT_NO_THROW(serialize(writer, empty_vector, default_options{}));

    vector_reader reader(writer.data());
    auto deserialized = deserialize<std::vector<int>>(reader, default_options{});
    EXPECT_TRUE(deserialized.empty());

    // 测试单元素容器
    std::vector<int> single_element = {42};
    vector_writer writer2;
    EXPECT_NO_THROW(serialize(writer2, single_element, default_options{}));

    vector_reader reader2(writer2.data());
    auto deserialized2 = deserialize<std::vector<int>>(reader2, default_options{});
    EXPECT_EQ(deserialized2.size(), 1);
    EXPECT_EQ(deserialized2[0], 42);
}

/**
 * 测试基本线程安全性
 */
TEST(ErrorHandlingTest, thread_safety_basic)
{
    std::vector<int> test_data = {1, 2, 3, 4, 5};
    std::vector<std::thread> threads;
    std::atomic<int> success_count{0};
    std::atomic<int> error_count{0};

    for (int i = 0; i < 10; ++i)
    {
        threads.emplace_back(
            [&test_data, &success_count, &error_count]()
            {
                try
                {
                    vector_writer writer;
                    serialize(writer, test_data, default_options{});

                    vector_reader reader(writer.data());
                    auto result = deserialize<std::vector<int>>(reader, default_options{});

                    if (result == test_data)
                    {
                        success_count++;
                    }
                }
                catch (...)
                {
                    error_count++;
                }
            });
    }

    for (auto & thread : threads)
    {
        thread.join();
    }

    EXPECT_EQ(success_count.load(), 10);
    EXPECT_EQ(error_count.load(), 0);
}

/**
 * 测试错误恢复机制
 */
TEST(ErrorHandlingTest, error_recovery)
{
    std::vector<int> test_data = {1, 2, 3, 4, 5};

    // 第一次尝试：使用会失败的写入器
    ThrowingWriter failing_writer(5);
    EXPECT_THROW(serialize(failing_writer, test_data, default_options{}), std::runtime_error);

    // 第二次尝试：使用正常的写入器（错误恢复）
    vector_writer normal_writer;
    EXPECT_NO_THROW(serialize(normal_writer, test_data, default_options{}));

    // 验证恢复后的序列化是正确的
    vector_reader reader(normal_writer.data());
    auto result = deserialize<std::vector<int>>(reader, default_options{});
    EXPECT_EQ(result, test_data);
}